package com.joysuch.wwyt.util;

import com.google.gson.reflect.TypeToken;
import com.joysuch.wwyt.workflow.api.bean.PersonTrajectoryResp;
import com.joysuch.wwyt.workflow.api.bean.ResultDataList;
import com.joysuch.wwyt.workflow.api.bean.TrajectoryPoint;

import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

public class RegionUtil {

    private static final double EARTH_RADIUS = 6378137;

    /**
     * @param pointLat  纬度
     * @param centerLng 纬度
     * @param pointLng  经度
     * @param centerLat 经度
     * @param radius    判断一个点是否在圆形区域内,比较坐标点与圆心的距离是否小于半径
     */
    public static boolean isInCircle(double pointLat, double pointLng, double centerLat, double centerLng, double radius) {
        double distance = getDistance(pointLat, pointLng, centerLat, centerLng);
        return !(distance > radius);
    }

    /**
     * 判断是否在多边形区域内
     *
     * @param pointLon 要判断的点的横坐标 经度
     * @param pointLat 要判断的点的纵坐标 维度
     * @param lon      区域各顶点的横坐标数组
     * @param lat      区域各顶点的纵坐标数组
     * @return
     */
    public static boolean isInPolygon(double pointLon, double pointLat, Double[] lon,
                                      Double[] lat) {
        if (lon != null && lon.length > 0 && lat != null && lat.length > 0) {
            // 将要判断的横纵坐标组成一个点
            Point2D.Double signPoint = new Point2D.Double(pointLon, pointLat);
            // 将区域各顶点的横纵坐标放到一个点集合里面
            List<Point2D.Double> areaPointList = new ArrayList<>();
            double polygonPointX = 0.0, polygonPointY = 0.0;
            for (int i = 0; i < lon.length; i++) {
                polygonPointX = lon[i];
                polygonPointY = lat[i];
                Point2D.Double polygonPoint = new Point2D.Double(polygonPointX, polygonPointY);
                areaPointList.add(polygonPoint);
            }
            return check(signPoint, areaPointList);
        }
        return false;
    }

    /**
     * @param signPoint 签字点的横纵坐标
     * @param polygon   区域的顶点坐标集合
     * @return
     */
    private static boolean check(Point2D.Double signPoint, List<Point2D.Double> polygon) {
        GeneralPath generalPath = new GeneralPath();

        Point2D.Double first = polygon.get(0);
        // 通过移动到指定坐标（以双精度指定），将一个点添加到路径中
        generalPath.moveTo(first.x, first.y);
        polygon.remove(0);
        for (Point2D.Double d : polygon) {
            // 通过绘制一条从当前坐标到新指定坐标（以双精度指定）的直线，将一个点添加到路径中
            generalPath.lineTo(d.x, d.y);
        }
        // 将几何多边形封闭
        generalPath.lineTo(first.x, first.y);
        generalPath.closePath();
        //Point2D 是否在 Shape 的边界内。
        return generalPath.contains(signPoint);
    }

    /**
     * 通过经纬度获取距离(单位：米)
     *
     * @param lat1 纬度1
     * @param lng1 经度1
     * @param lat2 纬度2
     * @param lng2 经度2
     * @return 距离
     */
    public static double getDistance(double lat1, double lng1, double lat2,
                                     double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        return s;
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }


    public static void main(String[] args) {

       /* double pointLon = 120.737332;
        double pointLat = 31.268348;
        double centerLon = 120.737274;
        double centerLat = 31.26848;
        double radius = 50;
        System.out.println("改点是否在圆内:" + isInCircle(pointLat, pointLon, centerLat, centerLon, radius));*/

        String response="{\"data\":[{\"t0\":1629420927022,\"t1\":1629420986291,\"buildId\":\"202272\",\"floorId\":1,\"points\":[{\"time\":1629420927022,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420926914},{\"time\":1629420928025,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420926914},{\"time\":1629420929028,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420928917},{\"time\":1629420930031,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420928917},{\"time\":1629420931034,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420930914},{\"time\":1629420932037,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420930914},{\"time\":1629420933039,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420930914},{\"time\":1629420934042,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420933082},{\"time\":1629420935045,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420934913},{\"time\":1629420936047,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420934913},{\"time\":1629420937050,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420936917},{\"time\":1629420938053,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420936917},{\"time\":1629420939056,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420938914},{\"time\":1629420940058,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420938914},{\"time\":1629420941061,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420940956},{\"time\":1629420942064,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420940956},{\"time\":1629420943067,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420942914},{\"time\":1629420945071,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420944913},{\"time\":1629420946074,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420944913},{\"time\":1629420947077,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420946915},{\"time\":1629420948080,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420946915},{\"time\":1629420949082,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420948915},{\"time\":1629420957088,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420956919},{\"time\":1629420958090,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420956919},{\"time\":1629420959093,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420958914},{\"time\":1629420960096,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420958914},{\"time\":1629420961099,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420958914},{\"time\":1629420962103,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420958914},{\"time\":1629420963106,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420958914},{\"time\":1629420966230,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420965474},{\"time\":1629420967234,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420965474},{\"time\":1629420968238,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420967474},{\"time\":1629420969242,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420967474},{\"time\":1629420970245,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420969432},{\"time\":1629420974252,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420973476},{\"time\":1629420975257,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420973476},{\"time\":1629420976262,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420975434},{\"time\":1629420977266,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420975434},{\"time\":1629420978270,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420977476},{\"time\":1629420979273,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420977476},{\"time\":1629420980276,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420979633},{\"time\":1629420981279,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420979633},{\"time\":1629420984284,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420983433},{\"time\":1629420985287,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420983433},{\"time\":1629420986291,\"x\":1021000,\"y\":173888,\"longitude\":105.20304826907413,\"latitude\":37.65301825008392,\"originalInfoId\":1629420985476}]}],\"errorCode\":0,\"errorMsg\":[]}\n";
        ResultDataList<PersonTrajectoryResp> result = GsonUtils.fromJson(response, new TypeToken<ResultDataList<PersonTrajectoryResp>>() {
        }.getType());
        PersonTrajectoryResp tj = result.getData().get(0);
        List<TrajectoryPoint> points = tj.getPoints();
        Double[] lon={105.20287492816354, 105.2030157441368, 105.20301976745034, 105.2028923625221, 105.20287492816354};
        Double[] lat={37.65290487488846, 37.652914430972636, 37.652495023898524, 37.652495023898524, 37.65290487488846};
        points.forEach(each->{
            System.out.println("改点是否在形状内:"+isInPolygon(each.getLongitude(),each.getLatitude(),lon,lat));
        });


       /* double pointLon=120.73726;
        double pointLat=31.268144;
        double centerLon=120.737274;
        double centerLat=31.26848;
        System.out.println(getDistance(pointLon,pointLat,centerLon,centerLat));*/
    }

}
